#include "executor.h"

// 构造函数（默认初始化状态）
Executor::Executor() 
    : currentX(0), 
      currentY(0), 
      currentHeading(Heading::HEADING_NORTH),
      isAccelerated(false),
      isReversed(false) {}

// 初始化函数（初始化状态重置）
void Executor::Init(int32_t x, int32_t y, char headingChar) {
    currentX = x;
    currentY = y;
    currentHeading = CharToHeading(headingChar);
    isAccelerated = false;
    isReversed = false;
}

// 新增：字符串指令批量执行
void Executor::ExecuteBatchCmds(const std::string& cmdStr) {
    std::vector<char> parsedCmds = ParseTRCommand(cmdStr);
    ExecuteBatchCmds(parsedCmds);
}

// 单指令执行函数
void Executor::ExecuteCmd(char cmd) {
    auto command = CreateCommand(cmd);
    if (command) {
        command->DoOperate(*this);
    } else {
        throw std::invalid_argument("无效指令：仅支持M/L/R/F/B/TR");
    }
}

// 批量指令执行函数（vector<char>版本）
void Executor::ExecuteBatchCmds(const std::vector<char>& cmds) {
    for (char cmd : cmds) {
        ExecuteCmd(cmd);
    }
}

// 状态查询函数（必须补充！）
Pose Executor::GetCurrentState() const {
    return {currentX, currentY, static_cast<char>(currentHeading)};
}

// 加速状态查询
bool Executor::IsAccelerated() const {
    return isAccelerated;
}

// 倒车状态查询
bool Executor::IsReversed() const {
    return isReversed;
}

// 字符转朝向
Executor::Heading Executor::CharToHeading(char c) {
    switch (c) {
        case 'N': return Heading::HEADING_NORTH;
        case 'E': return Heading::HEADING_EAST;
        case 'S': return Heading::HEADING_SOUTH;
        case 'W': return Heading::HEADING_WEST;
        default:
            throw std::invalid_argument("无效朝向：仅支持N/E/S/W");
    }
}

// 左转逻辑
void Executor::TurnLeft() {
    switch (currentHeading) {
        case Heading::HEADING_NORTH: currentHeading = Heading::HEADING_WEST; break;
        case Heading::HEADING_WEST:  currentHeading = Heading::HEADING_SOUTH; break;
        case Heading::HEADING_SOUTH: currentHeading = Heading::HEADING_EAST; break;
        case Heading::HEADING_EAST:  currentHeading = Heading::HEADING_NORTH; break;
    }
}

// 右转逻辑
void Executor::TurnRight() {
    switch (currentHeading) {
        case Heading::HEADING_NORTH: currentHeading = Heading::HEADING_EAST; break;
        case Heading::HEADING_EAST:  currentHeading = Heading::HEADING_SOUTH; break;
        case Heading::HEADING_SOUTH: currentHeading = Heading::HEADING_WEST; break;
        case Heading::HEADING_WEST:  currentHeading = Heading::HEADING_NORTH; break;
    }
}

// 前进逻辑
void Executor::MoveForward(int steps) {
    for (int i = 0; i < steps; ++i) {
        switch (currentHeading) {
            case Heading::HEADING_NORTH: currentY += 1; break;
            case Heading::HEADING_SOUTH: currentY -= 1; break;
            case Heading::HEADING_EAST:  currentX += 1; break;
            case Heading::HEADING_WEST:  currentX -= 1; break;
        }
    }
}

// 倒车逻辑
void Executor::MoveReverse(int steps) {
    for (int i = 0; i < steps; ++i) {
        switch (currentHeading) {
            case Heading::HEADING_NORTH: currentY -= 1; break;
            case Heading::HEADING_SOUTH: currentY += 1; break;
            case Heading::HEADING_EAST:  currentX -= 1; break;
            case Heading::HEADING_WEST:  currentX += 1; break;
        }
    }
}

// 切换加速状态
void Executor::ToggleAccelerated() {
    isAccelerated = !isAccelerated;
}

// 切换倒车状态
void Executor::ToggleReversed() {
    isReversed = !isReversed;
}

// 指令工厂函数（扩展TR映射）
std::unique_ptr<Executor::ICommand> Executor::CreateCommand(char cmd) {
    switch (cmd) {
        case 'M': return std::make_unique<MoveCommand>();
        case 'L': return std::make_unique<TurnLeftCommand>();
        case 'R': return std::make_unique<TurnRightCommand>();
        case 'F': return std::make_unique<FastCommand>();
        case 'B': return std::make_unique<ReverseCommand>();
        case 'Z': return std::make_unique<TurnRoundCommand>();
        default: return nullptr;
    }
}

// TR指令解析逻辑
std::vector<char> Executor::ParseTRCommand(const std::string& cmdStr) const noexcept {
    std::vector<char> parsedCmds;
    for (size_t i = 0; i < cmdStr.size(); ++i) {
        if (cmdStr[i] == 'T' && i + 1 < cmdStr.size() && cmdStr[i+1] == 'R') {
            parsedCmds.push_back('Z');
            ++i;
        } else {
            parsedCmds.push_back(cmdStr[i]);
        }
    }
    return parsedCmds;
}

// 移动指令实现
void Executor::MoveCommand::DoOperate(Executor& executor) const noexcept {
    int steps = 1;
    if (executor.isAccelerated) {
        steps = 2;
    }
    if (executor.IsReversed()) {
        executor.MoveReverse(steps);
    } else {
        executor.MoveForward(steps);
    }
}

// 左转指令实现
void Executor::TurnLeftCommand::DoOperate(Executor& executor) const noexcept {
    if (executor.IsReversed() && executor.isAccelerated) {
        executor.MoveReverse(1);
    }
    if (executor.IsReversed()) {
        executor.TurnRight();
    } else {
        if (executor.isAccelerated) {
            executor.MoveForward(1);
        }
        executor.TurnLeft();
    }
}

// 右转指令实现
void Executor::TurnRightCommand::DoOperate(Executor& executor) const noexcept {
    if (executor.IsReversed() && executor.isAccelerated) {
        executor.MoveReverse(1);
    }
    if (executor.IsReversed()) {
        executor.TurnLeft();
    } else {
        if (executor.isAccelerated) {
            executor.MoveForward(1);
        }
        executor.TurnRight();
    }
}

// 加速指令实现
void Executor::FastCommand::DoOperate(Executor& executor) const noexcept {
    executor.ToggleAccelerated();
}

// 倒车指令实现
void Executor::ReverseCommand::DoOperate(Executor& executor) const noexcept {
    executor.ToggleReversed();
}

// TR掉头指令实现
void Executor::TurnRoundCommand::DoOperate(Executor& executor) const noexcept {
    if (executor.IsReversed()) {
        return;
    }
    if (executor.IsAccelerated()) {
        executor.MoveForward(1);
        executor.TurnLeft();
        executor.MoveForward(1);
        executor.TurnLeft();
    } else {
        executor.TurnLeft();
        executor.MoveForward(1);
        executor.TurnLeft();
    }
}